home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 1).bin / MIPSSIM / asm16.c < prev    next >
C/C++ Source or Header  |  1999-12-02  |  25KB  |  1,118 lines

  1. #include <stdio.h>
  2. #include "define.h"
  3. void asmips16(char *base, FILE *fp);
  4.  
  5. #define MAXNAME 31
  6. #define MAXLABEL 10000
  7.  
  8. static ulong PC;
  9. static int   linenum;
  10. static int   extended;
  11.  
  12. #define LittleEndian 0
  13. #define BigEndian    1
  14.  
  15. static int endian = LittleEndian;
  16.  
  17. static struct {
  18.   char  name[MAXNAME+1];
  19.   ulong addr;
  20. } label_table[MAXLABEL];
  21.  
  22. static int labelp = -1;
  23.  
  24. #define B   0
  25. #define BX  1
  26. #define BC  2
  27. #define BCX 3
  28. #define JMP 4
  29. #define LA  5
  30.  
  31. static struct {
  32.   char name[MAXNAME+1];
  33.   ulong idx;
  34.   int   typ;
  35. } unsolved[MAXLABEL];
  36.  
  37. int unsolvedp = -1;
  38.  
  39. #define MAXLOCALF 16
  40. static ulong local_label[256];
  41. static int   for_llabel[256][MAXLOCALF];
  42. static int   typ_llabel[256][MAXLOCALF];
  43. static int   for_index[256];
  44.  
  45. static int search_label(char *);
  46. static int regist_label(char *, ulong); 
  47. static void regist_unsolv(char *,int);
  48.  
  49. typedef struct {
  50.   char    *nm;
  51.   void    (*type)(int);
  52.   uint    code;
  53. } TABLE;
  54.  
  55. static void ADDI_TYPE(int);
  56. static void B_TYPE(int);
  57. static void J_TYPE(int);
  58. static void R_TYPE(int);
  59. static void S_TYPE(int);
  60. static void LS_TYPE(int);
  61. static void I_TYPE(int);
  62.  
  63. #define _CODE(OP,FN)    (uint)((OP<<11)|FN)
  64.  
  65. static TABLE nmtab[]={
  66.   "addiu",      ADDI_TYPE,      _CODE(000,000),
  67.   "daddiu",     ADDI_TYPE,      _CODE(000,001),
  68.   "b",          B_TYPE,         _CODE(002,000),
  69.   "jal",        J_TYPE,         _CODE(003,000),
  70.   "jalx",       J_TYPE,         _CODE(003,001),
  71.   "beqz",       B_TYPE,         _CODE(004,000),
  72.   "bnez",       B_TYPE,         _CODE(005,000),
  73.   "sll",        S_TYPE,         _CODE(006,000),
  74.   "dsll",       S_TYPE,         _CODE(006,001),
  75.   "srl",        S_TYPE,         _CODE(006,002),
  76.   "sra",        S_TYPE,         _CODE(006,003),
  77.   "ld",         LS_TYPE,        _CODE(007,000),
  78.   "slti",       I_TYPE,         _CODE(012,000),
  79.   "sltiu",      I_TYPE,         _CODE(013,000),
  80.   "bteqz",      B_TYPE,         _CODE(014,000),
  81.   "btnez",      B_TYPE,         _CODE(014,001),
  82.   "move",       I_TYPE,         _CODE(014,000),
  83.   "li",         I_TYPE,         _CODE(015,000),
  84.   "cmpi",       I_TYPE,         _CODE(016,000),
  85.   "sd",         LS_TYPE,        _CODE(017,000),
  86.   "lb",         LS_TYPE,        _CODE(020,000),
  87.   "lh",         LS_TYPE,        _CODE(021,000),
  88.   "lw",         LS_TYPE,        _CODE(023,000),
  89.   "lbu",        LS_TYPE,        _CODE(024,000),
  90.   "lhu",        LS_TYPE,        _CODE(025,000),
  91.   "lwu",        LS_TYPE,        _CODE(027,000),
  92.   "sb",         LS_TYPE,        _CODE(030,000),
  93.   "sh",         LS_TYPE,        _CODE(031,000),
  94.   "sw",         LS_TYPE,        _CODE(033,000),
  95.   "daddu",      R_TYPE,         _CODE(034,000),
  96.   "addu",       R_TYPE,         _CODE(034,001),
  97.   "dsubu",      R_TYPE,         _CODE(034,002),
  98.   "subu",       R_TYPE,         _CODE(034,003),
  99.   "jalr",       R_TYPE,         _CODE(035,000),
  100.   "jr",         R_TYPE,         _CODE(035,000),
  101.   "slt",        R_TYPE,         _CODE(035,002),
  102.   "sltu",       R_TYPE,         _CODE(035,003),
  103.   "sllv",       R_TYPE,         _CODE(035,004),
  104.   "break",      R_TYPE,         _CODE(035,005),
  105.   "srlv",       R_TYPE,         _CODE(035,006),
  106.   "srav",       R_TYPE,         _CODE(035,007),
  107.   "dsrl",       S_TYPE,         _CODE(035,010),
  108.   "cmp",        R_TYPE,         _CODE(035,012),
  109.   "neg",        R_TYPE,         _CODE(035,013),
  110.   "and",        R_TYPE,         _CODE(035,014),
  111.   "or",         R_TYPE,         _CODE(035,015),
  112.   "xor",        R_TYPE,         _CODE(035,016),
  113.   "not",        R_TYPE,         _CODE(035,017),
  114.   "mfhi",       R_TYPE,         _CODE(035,020),
  115.   "mflo",       R_TYPE,         _CODE(035,022),
  116.   "dsra",       S_TYPE,         _CODE(035,023),
  117.   "dsllv",      R_TYPE,         _CODE(035,024),
  118.   "dsrlv",      R_TYPE,         _CODE(035,026),
  119.   "dsrav",      R_TYPE,         _CODE(035,027),
  120.   "mult",       R_TYPE,         _CODE(035,030),
  121.   "multu",      R_TYPE,         _CODE(035,031),
  122.   "div",        R_TYPE,         _CODE(035,032),
  123.   "divu",       R_TYPE,         _CODE(035,033),
  124.   "dmult",      R_TYPE,         _CODE(035,034),
  125.   "dmultu",     R_TYPE,         _CODE(035,035),
  126.   "ddiv",       R_TYPE,         _CODE(035,036),
  127.   "ddivu",      R_TYPE,         _CODE(035,037),
  128. /*END*/
  129. };
  130.  
  131. #define MAXTAB  (sizeof(nmtab)/sizeof(TABLE))
  132.  
  133. #define MAXBUFF 1024
  134. static char Line[MAXBUFF];
  135. static char tmpBuf[MAXBUFF];
  136.  
  137. static char *linep;
  138.  
  139. static ulong get_half(ulong addr)
  140. {
  141.   ulong word;
  142.  
  143.   word = get_word(addr);
  144.   if(addr&3)
  145.     return (word>>16)&0xffff;
  146.   else
  147.     return word&0xffff;
  148. }
  149.  
  150. static void put_half(ulong addr, ulong code)
  151. {
  152.   ulong word;
  153.  
  154.   word = get_word(addr);
  155.   if(addr&3)
  156.     word = (code<<16)|(word&0xffff);
  157.   else
  158.     word = (word&0xffff0000)|(code&0xffff);
  159.   put_word(addr,word);
  160. }
  161.  
  162. int regnum( char *reg)
  163. {
  164.   int     r;
  165.  
  166.   r= 0;
  167.   if(strcmp(reg,"r0")==0)  r=0;
  168.   if(strcmp(reg,"r1")==0)  r=1;
  169.   if(strcmp(reg,"r2")==0)  r=2;
  170.   if(strcmp(reg,"r3")==0)  r=3;
  171.   if(strcmp(reg,"r4")==0)  r=4;
  172.   if(strcmp(reg,"r5")==0)  r=5;
  173.   if(strcmp(reg,"r6")==0)  r=6;
  174.   if(strcmp(reg,"r7")==0)  r=7;
  175.   if(strcmp(reg,"r8")==0)  r=8;
  176.   if(strcmp(reg,"r9")==0)  r=9;
  177.   if(strcmp(reg,"r10")==0) r=10;
  178.   if(strcmp(reg,"r11")==0) r=11;
  179.   if(strcmp(reg,"r12")==0) r=12;
  180.   if(strcmp(reg,"r13")==0) r=13;
  181.   if(strcmp(reg,"r14")==0) r=14;
  182.   if(strcmp(reg,"r15")==0) r=15;
  183.   if(strcmp(reg,"r16")==0) r=16;
  184.   if(strcmp(reg,"r17")==0) r=17;
  185.   if(strcmp(reg,"r18")==0) r=18;
  186.   if(strcmp(reg,"r19")==0) r=19;
  187.   if(strcmp(reg,"r20")==0) r=20;
  188.   if(strcmp(reg,"r21")==0) r=21;
  189.   if(strcmp(reg,"r22")==0) r=22;
  190.   if(strcmp(reg,"r23")==0) r=23;
  191.   if(strcmp(reg,"r24")==0) r=24;
  192.   if(strcmp(reg,"r25")==0) r=25;
  193.   if(strcmp(reg,"r26")==0) r=26;
  194.   if(strcmp(reg,"r27")==0) r=27;
  195.   if(strcmp(reg,"r28")==0) r=28;
  196.   if(strcmp(reg,"r29")==0) r=29;
  197.   if(strcmp(reg,"r30")==0) r=30;
  198.   if(strcmp(reg,"r31")==0) r=31;
  199.   if(strcmp(reg,"zero")==0)r=0;
  200.   if(strcmp(reg,"at")==0)  r=1;
  201.   if(strcmp(reg,"v0")==0)  r=2;
  202.   if(strcmp(reg,"v1")==0)  r=3;
  203.   if(strcmp(reg,"a0")==0)  r=4;
  204.   if(strcmp(reg,"a1")==0)  r=5;
  205.   if(strcmp(reg,"a2")==0)  r=6;
  206.   if(strcmp(reg,"a3")==0)  r=7;
  207.   if(strcmp(reg,"t0")==0)  r=8;
  208.   if(strcmp(reg,"t1")==0)  r=9;
  209.   if(strcmp(reg,"t2")==0)  r=10;
  210.   if(strcmp(reg,"t3")==0)  r=11;
  211.   if(strcmp(reg,"t4")==0)  r=12;
  212.   if(strcmp(reg,"t5")==0)  r=13;
  213.   if(strcmp(reg,"t6")==0)  r=14;
  214.   if(strcmp(reg,"t7")==0)  r=15;
  215.   if(strcmp(reg,"s0")==0)  r=16;
  216.   if(strcmp(reg,"s1")==0)  r=17;
  217.   if(strcmp(reg,"s2")==0)  r=18;
  218.   if(strcmp(reg,"s3")==0)  r=19;
  219.   if(strcmp(reg,"s4")==0)  r=20;
  220.   if(strcmp(reg,"s5")==0)  r=21;
  221.   if(strcmp(reg,"s6")==0)  r=22;
  222.   if(strcmp(reg,"s7")==0)  r=23;
  223.   if(strcmp(reg,"t8")==0)  r=24;
  224.   if(strcmp(reg,"t9")==0)  r=25;
  225.   if(strcmp(reg,"k0")==0)  r=26;
  226.   if(strcmp(reg,"k1")==0)  r=27;
  227.   if(strcmp(reg,"gp")==0)  r=28;
  228.   if(strcmp(reg,"sp")==0)  r=29;
  229.   if(strcmp(reg,"s8")==0)  r=30;
  230.   if(strcmp(reg,"fp")==0)  r=30;
  231.   if(strcmp(reg,"ra")==0)  r=31;
  232.  
  233.   if(strcmp(reg,"pc")==0) r=0x1000;
  234.  
  235.   return r;
  236. }
  237.  
  238. static int search_label(char *nam)
  239. {
  240.   int i;
  241.  
  242.   for(i=0;i<=labelp;i++)
  243.     if(strcmp(label_table[i].name,nam)==0)
  244.       break;
  245.   if(i>labelp) return -1;/* not found */
  246.   return i;/* found */
  247. }
  248.  
  249. static int regist_label(char *nam, ulong pc)
  250. {
  251.   if(search_label(nam)>=0)
  252.     return -1;/* duplicated definition */
  253.   if((labelp+1)>=MAXLABEL)
  254.     return -2;/* table overflow */
  255.   ++labelp;
  256.   strncpy(label_table[labelp].name,nam,MAXNAME);
  257.   label_table[labelp].addr = pc;
  258.   return 0;
  259. }
  260.  
  261. static void regist_unsolv(char *nam, int typ)
  262. {
  263.   if((unsolvedp+1)>=MAXLABEL){
  264.     fprintf(stderr,"%d: too many unsolved labels!\n",linenum);
  265.     return;
  266.   }
  267.   unsolvedp++;
  268.   strncpy(unsolved[unsolvedp].name,nam,MAXNAME);
  269.   unsolved[unsolvedp].idx = PC;
  270.   unsolved[unsolvedp].typ = typ;
  271. }
  272.  
  273. static void add_label(ulong dst, int idx, int typ)
  274. {
  275.   ulong org;
  276.   ulong code;
  277.   long  imm;
  278.  
  279.   switch(typ){
  280.   case B:
  281.     org   = idx;
  282.     code  = get_half(idx);
  283.     code |= (((dst-(org+2))>>1)&0x7ff);
  284.     put_half(idx,code);
  285.     break;
  286.   case BC:
  287.     org   = idx;
  288.     code  = get_half(idx);
  289.     code |= (((dst-(org+2))>>1)&0xff);
  290.     put_half(idx,code);
  291.     break;
  292.   case BCX:
  293.     org  = idx;
  294.     imm  = (dst-(org+4))>>1;
  295.     code = (0xf000|(imm&0x7e0)|((imm>>11)&0x1f));
  296.     put_half(idx,code);
  297.     code = get_half(idx+2);
  298.     code|= (imm&0x1f);
  299.     put_half(idx+2,code);
  300.     break;
  301.   case JMP:
  302.     imm = (dst>>2)&0x3ffffff;
  303.     code = imm & 0xffff;
  304.     put_half(idx+2,code);
  305.     code = get_half(idx);
  306.     code |= (((imm>>11)&0x3e0)|((imm>>21)&0x1f));
  307.     put_half(idx,code);
  308.     break;
  309.   case LA:
  310.     code = get_half(idx+4);
  311.     code |= ((dst    )&0xffff);
  312.     put_half(idx+4,code);
  313.     code = get_half(idx+6);
  314.     code |= ((dst>>16)&0xffff);
  315.     put_half(idx+6,code);
  316.     break;
  317.   }
  318. }
  319.  
  320. static void solve_label(void)
  321. {
  322.   int i;
  323.   int l;
  324.  
  325.   for(i=0;i<=unsolvedp;i++){
  326.     if((l=search_label(unsolved[i].name))<0){
  327.       fprintf(stderr,"unsolved label: %s\n",unsolved[i].name);
  328.     }
  329.     else{
  330.       add_label(label_table[l].addr,unsolved[i].idx,unsolved[i].typ);
  331.     }
  332.   }
  333. }
  334.  
  335. static void solve_local(int n)
  336. {
  337.   int i;
  338.  
  339.   for(i=0;i<=for_index[n];i++){
  340.     add_label(local_label[n],for_llabel[n][i],typ_llabel[n][i]);
  341.   }
  342.   for_index[n] = -1;
  343. }
  344.  
  345. static void put_code(ulong addr, ulong code)
  346. {
  347.   if(extended==0){
  348.     put_half(addr,code);
  349.   }
  350.   else{
  351.     put_half(addr,code>>16);
  352.     put_half(addr+2,code);
  353.   }
  354. }
  355.  
  356. static int white(int ch)
  357. {
  358.   return (ch==' ')||(ch=='\t');
  359. }
  360.  
  361. static int eol(int ch)
  362. {
  363.   return (ch=='\n')||(ch=='\0')||(ch=='\r');
  364. }
  365.  
  366. static int delim(int ch)
  367. {
  368.   return (ch==',')||white(ch)||(ch=='(')||(ch==')')||(ch==':');
  369. }
  370.  
  371. static void scan_sym(char *to)
  372. {
  373.   while(delim(*linep)) linep++;
  374.   while((!eol(*linep)) && (!delim(*linep))) *to++ = *linep++;
  375.   if(*linep==':'){
  376.     *to++ = ':';
  377.     linep++;
  378.   }
  379.   *to='\0';
  380. }
  381.  
  382. static int chk_num(int ch, int rad)
  383. {
  384.   ch &= 0xff;
  385.   if(rad<=10){
  386.     ch=ch-'0';
  387.     if((ch>=0)&&(ch<rad)) return ch;
  388.     else return -1;
  389.   }
  390.   if(rad==16){
  391.     if((ch>='0')&&(ch<='9')) return ch-'0';
  392.     if((ch>='a')&&(ch<='f')) return ch-'a'+10;
  393.     if((ch>='A')&&(ch<='F')) return ch-'A'+10;
  394.     return -1;
  395.   }
  396.   return -1;
  397. }
  398.  
  399. static char  last_ch;
  400. static ulong label_value;
  401.  
  402. #define LABEL  0
  403. #define LOCALF 1
  404. #define LOCALB 2
  405. #define ADDR   3
  406.  
  407. static int check_label(char *sym)
  408. {
  409.   if((*sym<'0')||(*sym>'9'))
  410.     return LABEL;
  411.   label_value = (ulong)gen_val(sym);
  412.   if(last_ch=='f')
  413.     return LOCALF;
  414.   if(last_ch=='b')
  415.     return LOCALB;
  416.   return ADDR;
  417. }
  418.  
  419. static int islocal(char *sym)
  420. {
  421.   int v=0;
  422.  
  423.   while(*sym){
  424.     if((*sym<'0')||(*sym>'9'))
  425.       break;
  426.     v = v*10+(*sym-'0');
  427.     sym++;
  428.   }
  429.   if(*sym=='\0')
  430.     return v;
  431.   return 0;
  432. }
  433.  
  434. static void R_TYPE(int insn)
  435. {
  436.   int   fn;
  437.   int   rx,ry,rz;
  438.  
  439.   if(((fn=nmtab[insn].code)&(_CODE(037,000)))==(_CODE(034,000))){/* RRR */
  440.     scan_sym(tmpBuf);
  441.     rz = regnum(tmpBuf)&0x7;
  442.     scan_sym(tmpBuf);
  443.     rx = regnum(tmpBuf)&0x7;
  444.     scan_sym(tmpBuf);
  445.     ry = regnum(tmpBuf)&0x7;
  446.   }
  447.   else{ /* RR */
  448.     rz = 0;
  449.     if((fn&037)==0){/* J(AL)R */
  450.       scan_sym(tmpBuf);
  451.       rx = regnum(tmpBuf)&0x1f;
  452.       if(rx==31){ /* JR RA */
  453.     rx = 0;
  454.     ry = 1;
  455.       }
  456.       else{
  457.     rx &= 7;
  458.     if(strcmp(nmtab[insn].nm,"jr")==0)
  459.       ry = 0;
  460.     else
  461.       ry = 2;
  462.       }
  463.     }
  464.     else if(((fn&037)==020)||((fn&037)==022)){/* MFLO/MFHI */
  465.       scan_sym(tmpBuf);
  466.       rx = regnum(tmpBuf)&7;
  467.       ry = 0;
  468.       rz = 0;
  469.     }
  470.     else if(fn==_CODE(035,005)){/* BREAK */
  471.       scan_sym(tmpBuf);
  472.       rz = (int)gen_val(tmpBuf);
  473.       rx = (rz>>3)&7;
  474.       ry = rz&7;
  475.       rz = 0;
  476.     }
  477.     else{
  478.       scan_sym(tmpBuf);
  479.       rx = regnum(tmpBuf)&7;
  480.       scan_sym(tmpBuf);
  481.       ry = regnum(tmpBuf)&7;
  482.       rz = 0;
  483.       switch(fn&037){
  484.       case 004:/* SLLV */
  485.       case 006:/* SRLV */
  486.       case 007:/* SRAV */
  487.       case 024:/* DSLLV */
  488.       case 026:/* DSRLV */
  489.       case 027:/* DSRAV */
  490.     rz = rx;
  491.     rx = ry;
  492.     ry = rz;
  493.     rz = 0;
  494.       }
  495.     }
  496.   }
  497.   fn |= ((rx<<8)|(ry<<5)|(rz<<2));
  498.   extended = 0;
  499.   put_code(PC,fn);
  500. }
  501.  
  502. static void I_TYPE(int insn)
  503. {
  504.   int  fn;
  505.   int  rx,ry,rz;
  506.   long imm;
  507.   int  ex;
  508.  
  509.   if(((fn=nmtab[insn].code)&(_CODE(017,0)))==(_CODE(014,0))){/* MOVE */
  510.     extended = 0;
  511.     ex       = 0;
  512.     scan_sym(tmpBuf);
  513.     imm = regnum(tmpBuf);
  514.     scan_sym(tmpBuf);
  515.     ry = regnum(tmpBuf);
  516.     if((imm>7)||(imm==0)||(imm==1)){ /* MOV32R */
  517.       rx = 5;
  518.       rz = ry;
  519.       ry = imm & 7;
  520.       imm = (imm&0x18)|(rz&7);
  521.       rz = 0;
  522.     }
  523.     else{ /* MOVR32 */
  524.       rx = imm;
  525.       imm = ry;
  526.       ry  = rx;
  527.       rx = 7;
  528.       ry &= 7;
  529.       rz = 0;
  530.       imm &= 0x1f;
  531.     }
  532.   }
  533.   else{
  534.     scan_sym(tmpBuf);
  535.     rx = regnum(tmpBuf)&7;
  536.     ry = 0;
  537.     rz = 0;
  538.     scan_sym(tmpBuf);
  539.     imm = gen_val(tmpBuf);
  540.     if(extended||(imm&0xffffff00)){
  541.       extended = 1;
  542.       ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  543.       imm &= 0x1f;
  544.     }
  545.     else{
  546.       extended = 0;
  547.       ex       = 0;
  548.     }
  549.   }
  550.   fn |= ((rx<<8)|(ry<<5)|(rz<<2)|imm);
  551.   put_code(PC,(ulong)((ex<<16)|fn));
  552. }
  553.  
  554. static void B_TYPE(int insn)
  555. {
  556.   int   fn;
  557.   int   rx;
  558.   long  imm,imm2;
  559.   long  mask;
  560.   int   ex;
  561.   int   cl;
  562.  
  563.   switch(fn=nmtab[insn].code){
  564.   case _CODE(004,000):/* BEQZ */
  565.   case _CODE(005,000):/* BNEZ */
  566.     scan_sym(tmpBuf);
  567.     rx=regnum(tmpBuf);
  568.     mask=0xff;
  569.     break;
  570.   case _CODE(002,000):/* B */
  571.     rx=0;
  572.     mask=0x7ff;
  573.     break;
  574.   default:
  575.     rx=fn&1;
  576.     fn &= 0xff00;
  577.     mask=0xff;
  578.   }
  579.   scan_sym(tmpBuf);
  580.   if((cl=check_label(tmpBuf))==ADDR){
  581.     imm = (long)((label_value-(PC+2)))>>1;
  582.     if(imm<0)
  583.       imm = -imm;
  584.     if((imm>mask)||extended){
  585.       extended=1;
  586.       imm = (label_value-(PC+4))>>1;
  587.       ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  588.       imm &= 0x1f;
  589.     }
  590.     else{
  591.       imm = (label_value-(PC+2))>>1;
  592.       imm &= mask;
  593.       ex = 0;
  594.     }
  595.   }
  596.   else if(cl==LOCALB){
  597.     imm2 = (long)local_label[label_value&0xff];
  598.     imm = (long)((imm2-(PC+2)))>>1;
  599.     if(imm<0)
  600.       imm = -imm;
  601.     if((imm>mask)||extended){
  602.       extended=1;
  603.       imm = (imm2-(PC+4))>>1;
  604.       ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  605.       imm &= 0x1f;
  606.     }
  607.     else{
  608.       imm = (imm2-(PC+2))>>1;
  609.       imm &= mask;
  610.       ex = 0;
  611.     }
  612.   }
  613.   else if(cl==LOCALF){
  614.     cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  615.     for_llabel[label_value&0xff][cl]=PC;
  616.     typ_llabel[label_value&0xff][cl]=(extended)? BCX:
  617.                                   ((mask==0xff)? BC:B);
  618.     for_index[label_value&0xff]=cl;
  619.     imm = 0;
  620.     ex = 0;
  621.   }
  622.   else {
  623.     int i;
  624.     i = search_label(tmpBuf);
  625.     if(i<0){
  626.       regist_unsolv(tmpBuf,(extended)? BCX:BC);
  627.       imm = 0;
  628.       ex = 0;
  629.     }
  630.     else {
  631.       imm2 = (long)label_table[i].addr;
  632.       imm = (long)((imm2-(PC+2)))>>1;
  633.       if(imm<0)
  634.     imm = -imm;
  635.       if((imm>mask)||extended){
  636.     extended=1;
  637.     imm = (imm2-(PC+4))>>1;
  638.     ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  639.     imm &= 0x1f;
  640.       }
  641.       else{
  642.     imm = (imm2-(PC+2))>>1;
  643.     imm &= mask;
  644.     ex = 0;
  645.       }
  646.     }
  647.   }
  648.   put_code(PC,(ulong)((ex<<16)|(fn)|(rx<<8)|imm));
  649. }
  650.  
  651. static void J_TYPE(int insn)
  652. {
  653.   ulong targ;
  654.   ulong code;
  655.   int   rx,fn;
  656.   int   cl;
  657.  
  658.   extended = 1;
  659.   scan_sym(tmpBuf);
  660.   if((cl=check_label(tmpBuf))==ADDR){
  661.     targ = gen_val(tmpBuf);
  662.     targ =(targ>>2)&0x3ffffff;
  663.   }
  664.   else if(cl==LOCALB){
  665.     targ = local_label[label_value&0xff];
  666.     targ =(targ>>2)&0x3ffffff;
  667.   }
  668.   else if(cl==LOCALF){
  669.     cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  670.     for_llabel[label_value&0xff][cl]=PC;
  671.     typ_llabel[label_value&0xff][cl]=JMP;
  672.     for_index[label_value&0xff]=cl;
  673.     targ = 0;
  674.   }
  675.   else {
  676.     int i;
  677.     i = search_label(tmpBuf);
  678.     if(i<0){
  679.       regist_unsolv(tmpBuf,JMP);
  680.       targ = 0;
  681.     }
  682.     else {
  683.       targ = label_table[i].addr;
  684.       targ=(targ>>2)&0x3ffffff;
  685.     }
  686.   }
  687.   fn = nmtab[insn].code;
  688.   rx = fn&1;
  689.   code =(fn&0xfffe)|
  690.         ((targ&0xffff)<<16)|
  691.         ((targ>>11)&0x3e0)|
  692.         ((targ>>21)&0x1f)|
  693.         (rx<<10);
  694.   code = (code<<16)|((code>>16)&0xffff);
  695.   put_code(PC,code);
  696. }
  697.  
  698. static void ADDI_TYPE(int insn)
  699. {
  700.   int  d;
  701.   int  ex,c;
  702.   int  rx,ry;
  703.   long imm,imm2;
  704.  
  705.   if((nmtab[insn].code)==_CODE(0,0))
  706.     d=0x00;/* ADDIU */
  707.   else
  708.     d=0x10;/* DADDIU */
  709.   scan_sym(tmpBuf);
  710.   rx=regnum(tmpBuf);
  711.   scan_sym(tmpBuf);
  712.   ry=regnum(tmpBuf);
  713.   if(ry==0){ /* ADDIU rx,imm    */
  714.     imm = gen_val(tmpBuf);
  715.     imm2 = (imm<0)? -imm: imm;
  716.     if(rx==29){/* SP */
  717.       rx=0;
  718.       if(d)
  719.     c = 0xfb00;
  720.       else
  721.     c = 0x6300;
  722.       imm2 &= 0xffffff80;
  723.       if(imm2||extended){
  724.     extended = 1;
  725.     ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  726.     imm &= 0x1f;
  727.       }
  728.       else
  729.     imm = (imm>>3)&0xff;
  730.     }
  731.     else{
  732.       if(d){
  733.     ry=rx;
  734.     rx=0;
  735.     c = 0xfd00;
  736.     imm2 &= 0xfffffff0;
  737.       }
  738.       else{
  739.     c = 0x4800;
  740.     imm2 &= 0xffffff80;
  741.       }
  742.       if(imm2||extended){
  743.     extended = 1;
  744.     ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  745.     imm &= 0x1f;
  746.       }
  747.       else{
  748.     if(d)
  749.       imm = imm&0x1f;
  750.     else
  751.       imm = imm&0xff;
  752.       }
  753.     }
  754.   }
  755.   else{      /* ADDIU ry,rx,imm */
  756.     scan_sym(tmpBuf);
  757.     imm = gen_val(tmpBuf);
  758.     imm2 = (imm<0)? -imm: imm;
  759.     if(ry==0x1000){/* PC */
  760.       if(d){
  761.     ry = rx;
  762.     rx = 0;
  763.     c = 0xfe00;
  764.       }
  765.       else{
  766.     ry = 0;
  767.     c = 0x0800;
  768.       }
  769.       imm  >>= 2;
  770.       imm2 >>= 2;
  771.       imm2 &= 0xffffff80;
  772.       if((imm<0)||imm2||extended){
  773.     extended = 1;
  774.     imm <<= 2;
  775.     ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  776.     imm &= 0x1f;
  777.       }
  778.       else{
  779.     ex = 0;
  780.     imm &= 0xff;
  781.       }
  782.     }
  783.     else if(ry==29){/* SP */
  784.       if(d){
  785.     ry=rx;
  786.     rx=0;
  787.     c = 0xff00;
  788.       }
  789.       else{
  790.     ry = 0;
  791.     c = 0x0000;
  792.       }
  793.       imm  >>= 2;
  794.       imm2 >>= 2;
  795.       imm2 &= 0xffffff80;
  796.       if((imm<0)||imm2||extended){
  797.     extended = 1;
  798.     imm <<= 2;
  799.     ex = 0xf000|(imm&0x7e0)|((imm>>11)&0x1f);
  800.     imm &= 0x1f;
  801.       }
  802.       else{
  803.     ex = 0;
  804.     imm &= 0xff;
  805.       }
  806.     }
  807.     else{
  808.       c = ry;
  809.       ry = rx;
  810.       rx = c;
  811.       c = 0x4000+d;
  812.       imm2 &= 0xfffffff8;
  813.       if(imm2||extended){
  814.     extended = 1;
  815.     ex = 0xf000|(imm&0x7f0)|((imm>>11)&0xf);
  816.     imm &= 0xf;
  817.       }
  818.       else{
  819.     ex = 0;
  820.     imm &= 0xf;
  821.       }
  822.     }
  823.   }
  824.   put_code(PC,(ulong)((ex<<16)|c|(rx<<8)|(ry<<5)|imm));
  825. }
  826.  
  827. static void LS_TYPE(int insn)
  828. {
  829.   int  rx,ry;
  830.   long offset,offset2;
  831.   int  fn;
  832.   int  sa;
  833.   int  ex;
  834.  
  835.   scan_sym(tmpBuf);
  836.   ry=regnum(tmpBuf);
  837.   scan_sym(tmpBuf);
  838.   offset=gen_val(tmpBuf);
  839.   scan_sym(tmpBuf);
  840.   rx=regnum(tmpBuf);
  841.   switch(fn=nmtab[insn].code){
  842.   case _CODE(021,000):/* LH */
  843.   case _CODE(025,000):/* LHU */
  844.   case _CODE(031,000):/* SH */
  845.     sa=1;
  846.     break;
  847.   case _CODE(023,000):/* LW/SW */
  848.   case _CODE(033,000):/* LW/SW */
  849.   case _CODE(027,000):/* LWU */
  850.     sa=2;
  851.     break;
  852.   case _CODE(007,000):/* LD */
  853.   case _CODE(017,000):/* SD */
  854.     sa=3;
  855.     break;
  856.   default:/* LB/LBU/SB */
  857.     sa=0;
  858.   }
  859.   offset2=offset>>sa;
  860.   if((offset<0)||(offset2&0xffffffe0)||extended){
  861.     extended=1;
  862.     ex=0xf000|(offset&0x7e0)|((offset>>11)&0x1f);
  863.     offset &= 0x1f;
  864.   }
  865.   else{
  866.     ex=0;
  867.     offset=offset2&0x1f;
  868.   }
  869.   if((sa==2)||(sa==3)){
  870.     switch(fn){
  871.     case _CODE(023,000):/* LW */
  872.       if(rx==29){ /* SP */
  873.     rx=ry;
  874.     ry=0;
  875.     fn=0x9000;
  876.       }
  877.       else if(rx==0x1000){/* PC */
  878.     rx=ry;
  879.     ry=0;
  880.     fn=0xb000;
  881.       }
  882.       break;
  883.     case _CODE(007,000):/* LD */
  884.       if(rx==29){ /* SP */
  885.     rx=0;
  886.     fn=0xf800;
  887.       }
  888.       else if(rx==0x1000){/* PC */
  889.     rx=4;
  890.     fn=0xf800;
  891.       }
  892.       break;
  893.     case _CODE(033,000):/* SW */
  894.       if(rx==29){/* SP */
  895.     if(ry==31){/* RA */
  896.       rx=2;
  897.       ry=0;
  898.       fn=0x6000;
  899.     }
  900.     else{
  901.       rx=ry;
  902.       ry=0;
  903.       fn=0xd000;
  904.     }
  905.       }
  906.       break;
  907.     case _CODE(017,000):/* SD */
  908.       if(rx==29){/* SP */
  909.     if(ry==31){/* RA */
  910.       rx=2;
  911.       ry=0;
  912.       fn=0xf800;
  913.     }
  914.     else{
  915.       rx=1;
  916.       fn=0xf800;
  917.     }
  918.       }
  919.       break;
  920.     }
  921.   }
  922.   rx &= 7;
  923.   ry &= 7;
  924.   put_code(PC,(ulong)((ex<<16)|fn|(rx<<8)|(ry<<5)|offset));
  925. }
  926.  
  927. static void S_TYPE(int insn)
  928. {
  929.   int  rx,ry;
  930.   int  fn;
  931.   int  ex;
  932.   long sa;
  933.  
  934.   switch(fn=nmtab[insn].code){
  935.   case _CODE(035,010):/* DSRL */
  936.   case _CODE(035,023):/* DSRA */
  937.     scan_sym(tmpBuf);
  938.     ry=regnum(tmpBuf)&0x7;
  939.     scan_sym(tmpBuf);
  940.     sa=gen_val(tmpBuf)&0x3f;
  941.       if((sa==0)||(sa>8)||extended){
  942.       extended=1;
  943.       rx=0;
  944.       ex=0xf000|((sa&0x1f)<<6)|(sa&0x20);
  945.     }
  946.     else{
  947.       rx=sa&0x7;
  948.       ex=0;
  949.     }
  950.     sa=0;
  951.   break;
  952.   default:
  953.     scan_sym(tmpBuf);
  954.     rx=regnum(tmpBuf)&0x7;
  955.     scan_sym(tmpBuf);
  956.     ry=regnum(tmpBuf)&0x7;
  957.     scan_sym(tmpBuf);
  958.     sa=gen_val(tmpBuf)&0x3f;
  959.     if((sa==0)||(sa>8)||extended){
  960.       extended=1;
  961.       ex=0xf000|((sa&0x1f)<<6)|(sa&0x20);
  962.       sa=0;
  963.     }
  964.     else{
  965.       ex=0;
  966.       sa &= 0x7;
  967.     }
  968.   }
  969.   put_code(PC,(ulong)((ex<<16)|fn|(rx<<8)|(ry<<5)|(sa<<2)));
  970. }
  971.  
  972. static ulong asmcpu(ulong pc, char *buf)
  973. {
  974.   int   i;
  975.   long tmp;
  976.   int   reg;
  977.  
  978.   labelp = -1;
  979.   unsolvedp = -1;
  980.  
  981.   for(i=0;i<MAXTAB;i++)
  982.     if(strcmp(tmpBuf,nmtab[i].nm)==0) break;
  983.   if(i>=MAXTAB){
  984.     if(strcmp(tmpBuf,"nop")==0){
  985.       put_code(PC,0xEA4D);
  986.       return PC+2;
  987.     }
  988.     if(strcmp(tmpBuf,".org")==0){
  989.       scan_sym(tmpBuf);
  990.       return (ulong)gen_val(tmpBuf);
  991.     }
  992.     if(strcmp(tmpBuf,".align")==0){
  993.       scan_sym(tmpBuf);
  994.       tmp = gen_val(tmpBuf);
  995.       return PC+(tmp-(PC%tmp));
  996.     }
  997.     if(strcmp(tmpBuf,".word")==0){
  998.       extended = 0;
  999.       scan_sym(tmpBuf);
  1000.       while(tmpBuf[0]!='\0'){
  1001.     tmp = gen_val(tmpBuf);
  1002.     if(endian==LittleEndian){
  1003.       put_code(PC+0,(tmp&0xffff));
  1004.       put_code(PC+2,((tmp>>16)&0xffff));
  1005.     }
  1006.     else{
  1007.       put_code(PC+0,((tmp>>16)&0xffff));
  1008.       put_code(PC+2,(tmp&0xffff));
  1009.     }
  1010.     PC += 4;
  1011.     scan_sym(tmpBuf);
  1012.       }
  1013.       return PC;
  1014.     }
  1015.     if(strcmp(tmpBuf,"la")==0){
  1016.       int cl;
  1017.       extended = 0;
  1018.       if(PC&3){
  1019.     put_code(PC,0xEA4D);
  1020.     PC += 2;
  1021.       }
  1022.       scan_sym(tmpBuf);
  1023.       reg = regnum(tmpBuf)&0x7;
  1024.       scan_sym(tmpBuf);
  1025.       if((cl=check_label(tmpBuf))==ADDR){
  1026.     tmp = gen_val(tmpBuf);
  1027.       }
  1028.       else if(cl==LOCALB){
  1029.     tmp = local_label[label_value&0xff];
  1030.       }
  1031.       else if(cl==LOCALF){
  1032.     cl = (for_index[label_value&0xff]+1) % MAXLOCALF;
  1033.     for_llabel[label_value&0xff][cl]=PC;
  1034.     typ_llabel[label_value&0xff][cl]=LA;
  1035.     for_index[label_value&0xff]=cl;
  1036.     tmp = 0;
  1037.       }
  1038.       else {
  1039.     int i;
  1040.     i = search_label(tmpBuf);
  1041.     if(i<0){
  1042.       regist_unsolv(tmpBuf,LA);
  1043.       tmp = 0;
  1044.     }
  1045.     else {
  1046.       tmp = label_table[i].addr;
  1047.     }
  1048.       }
  1049.       put_code(PC+0,0xb001|(reg<<8));
  1050.       put_code(PC+2,0x1002);
  1051.       if(endian==LittleEndian){
  1052.     put_code(PC+4,(tmp&0xffff));
  1053.     put_code(PC+6,((tmp>>16)&0xffff));
  1054.       }
  1055.       else{
  1056.     put_code(PC+4,((tmp>>16)&0xffff));
  1057.     put_code(PC+6,(tmp&0xffff));
  1058.       }
  1059.       return PC+8;
  1060.     }
  1061.     if(tmpBuf[0]==0)
  1062.       return pc;
  1063.     fprintf(stderr,"%d: unknown nmemonic!\n",linenum);
  1064.     return pc;
  1065.   }
  1066.   (nmtab[i].type)(i);
  1067.   i = (extended)? 4: 2;
  1068.   extended = 0;
  1069.   return pc+i;
  1070. }
  1071.  
  1072. void asmips16(char *base, FILE *fp)
  1073. {
  1074.   int  i;
  1075.  
  1076.   if(*base!='\0')
  1077.     PC = gen_val(base);
  1078.   linenum = 0;
  1079.   for(i=1;i<256;i++)
  1080.     for_index[i] = -1;
  1081.   printf("%08x ",PC);fflush(stdout);
  1082.   while(fgets(Line,MAXBUFF,fp)!=NULL){
  1083.     linep = Line;
  1084.     linenum++;
  1085.     scan_sym(tmpBuf);
  1086.     if(tmpBuf[0]=='q')/* quit */
  1087.       break;
  1088.     if(tmpBuf[0]=='\0')/* null line */
  1089.       goto next;
  1090.     if(tmpBuf[0]=='#')  /* comment line */
  1091.       goto next;
  1092.     i = strlen(tmpBuf);
  1093.     if(tmpBuf[i-1]==':'){ /* label */
  1094.       /* process label */
  1095.       tmpBuf[i-1]='\0';
  1096.       if(i=islocal(tmpBuf)){
  1097.         local_label[i&0xff]=PC;
  1098.         solve_local(i&0xff);
  1099.       }
  1100.       else if(regist_label(tmpBuf,PC)<0)
  1101.         fprintf(stderr,"%d: label error!\n",linenum);
  1102.       scan_sym(tmpBuf);
  1103.       if(tmpBuf[0]=='\0')
  1104.         goto next;
  1105.     }
  1106.     if((i>1)&&(tmpBuf[i-1]=='e')&&(tmpBuf[i-2]=='.')){
  1107.       extended = 1;
  1108.       tmpBuf[i-2]='\0';
  1109.     }
  1110.     else
  1111.       extended = 0;
  1112.     PC = asmcpu(PC,tmpBuf);
  1113.   next:
  1114.     printf("%08x ",PC);fflush(stdout);
  1115.   }
  1116.   solve_label();
  1117. }
  1118.